home *** CD-ROM | disk | FTP | other *** search
/ Freelog 22 / freelog 22.iso / Prog / Djgpp / GPC2952B.ZIP / doc / gpc / demos / pipedemo.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2001-02-09  |  5.2 KB  |  154 lines

  1. {
  2. GPC demo program for the Pipe unit.
  3. Inter-process communication using pipes on multi-tasking systems,
  4. emulated on single-tasking systems.
  5.  
  6. Copyright (C) 1999-2001 Free Software Foundation, Inc.
  7.  
  8. Author: Frank Heckenbach <frank@pascal.gnu.de>
  9.  
  10. This program is free software; you can redistribute it and/or
  11. modify it under the terms of the GNU General Public License as
  12. published by the Free Software Foundation, version 2.
  13.  
  14. This program is distributed in the hope that it will be useful,
  15. but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. GNU General Public License for more details.
  18.  
  19. You should have received a copy of the GNU General Public License
  20. along with this program; see the file COPYING. If not, write to
  21. the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  22. Boston, MA 02111-1307, USA.
  23.  
  24. As a special exception, if you incorporate even large parts of the
  25. code of this demo program into another program with substantially
  26. different functionality, this does not cause the other program to
  27. be covered by the GNU General Public License. This exception does
  28. not however invalidate any other reasons why it might be covered
  29. by the GNU General Public License.
  30. }
  31.  
  32. program PipeDemo;
  33.  
  34. uses GPC, Pipe;
  35.  
  36. const
  37.   ResultMessage : array [TWaitPIDResult] of TString =
  38.     ('did not terminate with status ',
  39.      'terminated with status ',
  40.      'was teminated by signal ',
  41.      'was stopped by signal ',
  42.      'did something unexpected with status ');
  43.  
  44. var
  45.   ToInput : Text;
  46.   FromOutput, FromStdErr : File;
  47.   Process : PPipeProcess;
  48.   WaitPIDResult : TWaitPIDResult;
  49.   Status : Integer;
  50.   Files : array [1 .. 2] of PAnyFile;
  51.  
  52. { Check for output while reading input. }
  53. procedure CheckProcessOutput (TimeOut : LongInt);
  54. const Names : array [1 .. 2] of String [6] = ('Output', 'StdErr');
  55. var
  56.   Nr, BytesRead : Integer;
  57.   LastNr : static Integer = 0;
  58.   Buffer : array [1 .. 256] of Char;
  59. begin
  60.   Nr := - 1;
  61.   while (Nr <> 0) and ((Files [1] <> nil) or (Files [2] <> nil)) do
  62.     begin
  63.       Nr := IOSelectRead (Files, TimeOut);
  64.       if Nr < 0 then
  65.         begin
  66.           Writeln (StdErr, 'Error in `IOSelect''');
  67.           Halt (1)
  68.         end;
  69.       if Nr > 0 then
  70.         begin
  71.           BlockRead (File (Files [Nr]^), Buffer, SizeOf (Buffer), BytesRead);
  72.           if BytesRead = 0 then
  73.             Files [Nr] := nil
  74.           else
  75.             begin
  76.               if LastNr <> Nr then
  77.                 begin
  78.                   LastNr := Nr;
  79.                   Write ('[', Names [Nr], ']')
  80.                 end;
  81.               Write (Buffer [1 .. BytesRead])
  82.             end
  83.         end
  84.     end
  85. end;
  86.  
  87. procedure DemoProcedure;
  88. var s : TString;
  89. begin
  90.   Writeln (StdErr, 'Forking, but not executing another process...');
  91.   while not EOF do
  92.     begin
  93.       Readln (s);
  94.       Writeln ('Writing `', s, ''' to Output.');
  95.       Writeln (StdErr, 'Writing `', s, ''' to Error.')
  96.     end
  97. end;
  98.  
  99. begin
  100.   Writeln ('Demo for using pipes and forking. By default, the program will fork');
  101.   Writeln ('and execute DemoProc as a separate executable, and emulate this on');
  102.   Writeln ('limited operating systems (e.g., Dos). If you give the command line');
  103.   Writeln ('parameter `-f'', the program will only fork, but not execute');
  104.   Writeln ('another process, but rather an internal procedure.');
  105.   Writeln;
  106.   if PipeForking
  107.     then Writeln ('Using fork on this system.')
  108.     else Writeln ('Emulating fork on this system.');
  109.   Writeln;
  110.   { Also search for demoproc in the directory of this executable, if available }
  111.   SetEnv (PathEnvVar, DirFromPath (ExecutablePath) + PathSeparator + GetEnv (PathEnvVar));
  112.   { Start a process with pipes }
  113.   {$I-}
  114.   if ParamStr (1) = '-f'
  115.     then Pipe (ToInput, (*@@anyfile*)AnyFile( FromOutput), (*@@anyfile*)AnyFile( FromStdErr), '', null, GetCEnvironment, Process, DemoProcedure)
  116.     else Pipe (ToInput, (*@@anyfile*)AnyFile( FromOutput), (*@@anyfile*)AnyFile( FromStdErr), 'demoproc', null, GetCEnvironment, Process, nil);
  117.   {$I+}
  118.   if IOResult <> 0 then
  119.     begin
  120.       Writeln (StdErr, 'Could not create pipe to `demoproc''. Please compile `demoproc.pas'' first,');
  121.       Writeln (StdErr, 'and make sure the resulting executable can be found in your PATH.');
  122.       Halt (1)
  123.     end;
  124.  
  125.   { Set the variables where the process' status will be stored. }
  126.   Process^.Result := @WaitPIDResult;
  127.   Process^.Status := @Status;
  128.  
  129.   Files [1] := (*@@anyfile*)PAnyFile( @FromOutput);
  130.   Files [2] := (*@@anyfile*)PAnyFile( @FromStdErr);
  131.  
  132.   { Pipe some input to the process }
  133.   CheckProcessOutput (0);
  134.   Writeln (ToInput, 'foo');
  135.   CheckProcessOutput (0);
  136.   Sleep (1);
  137.   Writeln (ToInput, 'bar');
  138.   CheckProcessOutput (0);
  139.  
  140.   Close (ToInput); { It's important to close ToInput here, so the process
  141.     will terminate. However, the effects of not closing ToInput are quite
  142.     different under Unix (waiting for more input from FromOutput or
  143.     FromStdErr) and Dos (never starting the process in the first place
  144.     and therefore not getting any data from FromOutput and FromStdErr!). }
  145.  
  146.   { Read all the remaining output }
  147.   CheckProcessOutput (- 1);
  148.  
  149.   Close (FromOutput);
  150.   Close (FromStdErr);
  151.   Writeln ('The process ', ResultMessage [WaitPIDResult], Status, '.');
  152.   if (WaitPIDResult = PIDExited) and (Status = 0) then Writeln ('This means success.')
  153. end.
  154.